import {Obj3d} from "./obj3d";
import {Light} from "../lights/light";
import {Camera} from "./camera";
import {mat4, vec3} from "gl-matrix";
import {GameItem} from "../comps/gameItem";
import {Ray} from "../math/ray";


export class Scene {

    objects: Obj3d[] = [];
    lights: Light[] = [];


    // Deprecated
    add(obj: Obj3d) {
        this.addObject(obj);
    }


    addObject(object: Obj3d) {
        this.objects.push(object);
    }

    addLight(light: Light) {
        this.lights.push(light);
    }


    pick(screen_x:number,screen_y:number,camera:Camera){

        camera.updateMatrix();
        this.objects.forEach(obj=>obj.updateMatrix());

        let nearPos = camera.screen_to_clip(screen_x,screen_y,-1);
        let farPos = camera.screen_to_clip(screen_x,screen_y,1);
        vec3.transformMat4(nearPos,nearPos,camera.invProjMatrix);
        vec3.transformMat4(farPos,farPos,camera.invProjMatrix);


        let dir = vec3.create();
        vec3.sub(dir,farPos,nearPos);
        let ray = new Ray(nearPos,dir);

        let posInView = vec3.create();

        let selectedInfo = {
            z:Infinity,
            item:null
        };

        // 检查
        let objects = this.objects;
        let len = objects.length;
        for (let i = 0; i < len; ++i){
            let object = objects[i];
            if (object instanceof GameItem){
                // 检查
                // TODO: 应该分层, 只检查相应层的东西
                // 感觉放到 相机空间中计算更加方便
                let r = object.material.vertexData.radius;
                let scaledR = r * Math.max(object.scale[0],object.scale[1],object.scale[2]);

                // 物体在相机坐标系中的位置
                // mat4.mul(vm,camera.viewMatrix,object.matrix);
                mat4.getTranslation(posInView,object.matrix);
                vec3.transformMat4(posInView,posInView,camera.viewMatrix);

                if (posInView[2] - scaledR >= nearPos[2] ||
                    posInView[2] + scaledR <= farPos[2]){
                    // 外面
                    continue;
                }

                let distance = ray.distanceToPoint(posInView);
                if(distance <= scaledR){
                    // 相交了
                    if (!selectedInfo.item){
                        // @ts-ignore
                        selectedInfo.item = object;

                        // TODO:应该是获取交点
                        selectedInfo.z = posInView[2];
                    }else{
                        if (posInView[2] > selectedInfo.z){
                            selectedInfo.z = posInView[2];
                            // @ts-ignore
                            selectedInfo.item = object;
                        }
                    }
                }

                // TODO:线段和boundingbox 相交
            }
        }

        return selectedInfo.item;
    }

}
